import logger from '../logger';
import uuid from 'uuid';
import BroserClient from './Client';
import WebSocket from 'ws';
import { IncomingMessage } from 'http';
import Agent from './AgentManager';
import Message from './Message'




class BrowserClientsManager {
    private clients: Map<string, BroserClient>;
    private wss: WebSocket.Server | null = null;
    private toAgentMsgCallback: Message.onMessageCb | null = null;


    constructor() {
        this.clients = new Map();
    }

    start(nPort: number) {
        if (this.wss) {
            logger.error('wss 已经创建。port: ', this.wss.address());
            return;
        }
        this.wss = new WebSocket.Server({ port: nPort });
        this.wss.on('connection', (wsc: WebSocket, req: IncomingMessage) => {
            this.onConnect(wsc);
        });
    }
    setToAgentMsgCallback(agentMsgCallback: Message.onMessageCb) {
        this.toAgentMsgCallback = agentMsgCallback;
    }

    onConnect(wsc: WebSocket) {// wsc: websocket client.
        // 响应到了客户端连接。
        var strUUid: string = uuid.v4();
        logger.info(`新的客户端连接， 分配的uuid: ${strUUid}`);

        var bc: BroserClient = new BroserClient(strUUid, wsc);
        bc.setCloseCb((bc: BroserClient) => {
            this.onClose(bc);
        });
        bc.setMessageCb((bc: BroserClient, data: string) => {
            this.onClientMsg(bc, data);
        });
        this.clients.set(strUUid, bc);
    }
    onClose(bc: BroserClient) {
        logger.info(`uuid: ${bc.getUuid()} 客户端断开连接.`);
        this.clients.delete(bc.getUuid());
    }
    fromAgentMsg(data: Message.MsgBase): boolean {
        logger.info('recv from agent, data: ', data);
        let client: BroserClient | undefined = this.clients.get(data.uuid);
        if (client) {
            client.send(JSON.stringify(data));
        }
        else {
            logger.info('uuid: ', data.uuid, ' client is not exists.');
        }
        return true;
    }


    onClientMsg(bc: BroserClient, data: string) {
        var reqObj: Message.MsgBase = JSON.parse(data);
        reqObj.uuid = bc.getUuid();

        logger.info(`ws recv methpd: ${reqObj.method}, uuid: ${reqObj.uuid}, data: `, reqObj);
        switch (reqObj.method) {
            case Message.Method.LOGIN_REQ:
                this.onLoginReq(bc, <Message.LoginReq>(reqObj));
                break;
            case Message.Method.LOGOUT_REQ:
                this.onLogoutReq(bc, <Message.LogoutReq>(reqObj));
                break;
            case Message.Method.AICAHT_REQ:
                this.onAiChatReq(bc, <Message.AiChatReq>(reqObj));
                break;
        }
    }

    onLoginReq(bc: BroserClient, loginReq: Message.LoginReq) {
        logger.info(`onLoginReq method: ${loginReq.method} serviceId: ${loginReq.serviceId} appid: ${loginReq.appid} uname: ${loginReq.uname}`);
        bc.setServiceId(loginReq.serviceId);
        if (this.toAgentMsgCallback) {
            this.toAgentMsgCallback(loginReq);
        }
    }

    onLogoutReq(bc: BroserClient, logoutReq: Message.LogoutReq) {
        logger.info(`onLogoutReq method: ${logoutReq.method} appid: ${logoutReq.appid}`);
        logoutReq.serviceId = bc.getServiceId();
        if (this.toAgentMsgCallback) {
            this.toAgentMsgCallback(logoutReq);
        }
    }
    onAiChatReq(bc: BroserClient, aiChatReq: Message.AiChatReq) {
        logger.info(`onAiChatReq method: ${aiChatReq.method} appid: ${aiChatReq.appid} content: ${aiChatReq.content}`);
        aiChatReq.serviceId = bc.getServiceId();
        if (this.toAgentMsgCallback) {
            this.toAgentMsgCallback(aiChatReq);
        }
    }
}

export = BrowserClientsManager;